package com.xw.floatlib;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import com.xw.floatlib.callback.FloatCallBack;
import com.xw.floatlib.callback.MusicCallBack;
import com.xw.floatlib.view.PlayerStateData;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FloatMonkService extends Service implements FloatCallBack, MediaPlayer.OnPreparedListener {

    private static final String NOTIFICATION_PLAY_PAUSE = "notification_play_pause";
    private static final String NOTIFICATION_PRE = "notification_pre";
    private static final String NOTIFICATION_NEX = "notification_next";
    private static final String NOTIFICATION_CANCEL = "notification_cancel";
    private static final String TAG = "FloatMonkService";
    //通知栏
    private Notification notification;
    private NotificationManager notificationManager;
    private String channelID = "channelID";
    private CharSequence channelName = "channelName";
    private Notification.Builder builder;
    private RemoteViews remoteViews;
    private int id = 1;
    //音乐集合
    private List<MusicData> floatDataList = new ArrayList<>();
    //当前播放音乐在集合中的下标
    private int postion = -1;
    //判断悬浮窗是否被移除
    private boolean isCancle = true;

    //    private PLMediaPlayer mPlayer;
    private MediaPlayer mPlayer;
    private Handler handler = new Handler();
    private static Map<String, MusicCallBack> callBackMap = new HashMap<>();
    //调用registerCallback 的页面需要传递一个唯一id,callBackMap 回调根据这个唯一id执行
    private String mPlateID = "";
    private PlayerStateData stateData;
    private TelephonyManager mTelephonyManager;
    private PhoneStateListener mPhoneStateListener;
    //区分第一次进入的时候，电话监听不调用播放功能
    private boolean isFirstInit = true;
    private Bitmap imageIcon = null;
    private String imageIconPath = "";
    private AudioFocusManager audioFocusManager;

    public static void registerCallback(String plate_id, MusicCallBack musicCallBack) {
        callBackMap.put(plate_id, musicCallBack);
    }

    public static void unRegister(String plate_id) {
        callBackMap.remove(plate_id);
    }

    @Override
    public void onCreate() {
        super.onCreate();

        FloatActionController.getInstance().registerCallLittleMonk(this);
        audioFocusManager = new AudioFocusManager(this);
        audioFocusManager.requestAudioFocus();

        mPlayer = new MediaPlayer();
        mPlayer.setOnPreparedListener(this);

        IntentFilter filter = new IntentFilter();
        filter.addAction(NOTIFICATION_PLAY_PAUSE);
        filter.addAction(NOTIFICATION_PRE);
        filter.addAction(NOTIFICATION_NEX);
        filter.addAction(NOTIFICATION_CANCEL);
        registerReceiver(NotificationRecever, filter);

        stateData = new PlayerStateData();
        isFirstInit = true;
        startTelephonyListener();
    }

    /**********************************************电话监听*************************************************************/

    private void startTelephonyListener() {
        mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager == null) {
            Log.e(TAG, "Failed to initialize TelephonyManager!!!");
            return;
        }

        mPhoneStateListener = new PhoneStateListener() {

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                switch (state) {
                    case TelephonyManager.CALL_STATE_IDLE:
                        Log.d(TAG, "PhoneStateListener: CALL_STATE_IDLE");
                        if (mPlayer != null && !isFirstInit) {
                            stop2Start();
                        }
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        Log.d(TAG, "PhoneStateListener: CALL_STATE_OFFHOOK");
                        if (mPlayer != null && mPlayer.isPlaying()) {
                            stop2Start();
                        }
                        break;
                    case TelephonyManager.CALL_STATE_RINGING:
                        Log.d(TAG, "PhoneStateListener: CALL_STATE_RINGING: " + incomingNumber);
                        break;
                    default:
                        break;
                }
            }
        };
        try {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopTelephonyListener() {
        if (mTelephonyManager != null && mPhoneStateListener != null) {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
            mTelephonyManager = null;
            mPhoneStateListener = null;
        }
    }

    /************************************************监听结束********************************************************/

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        List<MusicData> musicData = (List<MusicData>) intent.getSerializableExtra("music_dates");
        if (musicData != null && !musicData.isEmpty()) {
            floatDataList.clear();
            floatDataList.addAll(musicData);
        }
        mPlateID = intent.getStringExtra("plate_id");
        playItem(intent.getIntExtra("start_index", -1), floatDataList, mPlateID);
        return super.onStartCommand(intent, flags, startId);
    }

    private void initWondow() {
        if (isCancle) {
            FloatWindowManager.createFloatWindow(this);
            isCancle = false;
        }

        FloatWindowManager.upDate(floatDataList);
        initMisic();
    }

    private void initMisic() {
        try {
            mPlayer.reset();
            mPlayer.setDataSource(floatDataList.get(postion).getPathUrl());
            mPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        audioFocusManager.abandonAudioFocus();
        FloatWindowManager.removeFloatWindowManager();
        stopTelephonyListener();
        unregisterReceiver(NotificationRecever);
        floatDataList.clear();
        mPlayer.stop();
        mPlayer.release();
        mPlayer = null;
        FloatActionController.getInstance().unRegisterCallbackMonk();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void show() {
        if (!FloatWindowManager.getFloatWindowState()) {
            FloatWindowManager.show();
        }
        FloatWindowManager.upDate(floatDataList);
    }

    @Override
    public void hide() {
        FloatWindowManager.hide();
    }

    @Override
    public void last() {
        switchMusic(-1);
    }

    private void switchMusic(int type) {
        if (floatDataList.size() < 2) return;
        if (type < 0) {
            if (postion < 1)
                postion = floatDataList.size() - 1;
            else
                postion--;
        } else {
            if (postion == floatDataList.size() - 1)
                postion = 0;
            else
                postion++;
        }

        imageIconPath = floatDataList.get(postion).getIamgePath();
        if (!TextUtils.isEmpty(imageIconPath)) {
            LoadImage loadImage = new LoadImage();
            loadImage.execute(imageIconPath);
        }
        initMisic();
        upDateNotification(true);
    }

    @Override
    public void next() {
        switchMusic(1);
    }

    //暂停/播放
    @Override
    public void stop2Start() {
        try {
            if (isPlaying()) {
                mPlayer.pause();
                upDateNotification(false);
                callBackMap.get(mPlateID).MusicPlatState(false);
            } else {
                mPlayer.start();
                handler.removeCallbacks(runnable);
                handler.post(runnable);
                upDateNotification(true);
                callBackMap.get(mPlateID).MusicPlatState(true);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void cancle() {
        try {
            callBackMap.get(mPlateID).MusicPlatState(false);
            postion = -1;
            stopForeground(true);
            notificationManager.cancel(id);
            handler.removeCallbacks(runnable);
            mPlayer.stop();
            FloatActionController.getInstance().stopMonkServer(this);
            isCancle = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updataProgress(int progress) {
        FloatWindowManager.updataProgress(progress, postion);
        seekTo(progress);
        stateData.setProgress(progress);
        if (callBackMap.get(mPlateID) != null)
            callBackMap.get(mPlateID).updateProgress(stateData);
    }

    @Override
    public void playItem(int index, List<MusicData> musicDataList, String plate_id) {

        if (postion == index) {
            if (musicDataList.get(postion).getMusicId().equals(floatDataList.get(postion).getMusicId())) {
                stop2Start();
                return;
            }
        }
        if (musicDataList.size() == floatDataList.size()) {
            for (int i = 0; i < musicDataList.size(); i++) {

                if (!musicDataList.get(i).getMusicId().equals(floatDataList.get(i).getMusicId())) {
                    this.floatDataList.clear();
                    this.floatDataList.addAll(musicDataList);
                    break;
                }
            }
        } else {
            this.floatDataList.clear();
            this.floatDataList.addAll(musicDataList);
        }

        this.postion = index;
        if (!mPlateID.equals(plate_id)) {
            mPlateID = plate_id;
        }

        if (TextUtils.isEmpty(imageIconPath) || !floatDataList.get(postion).getIamgePath().equals(imageIconPath)) {
            imageIconPath = floatDataList.get(postion).getIamgePath();

            LoadImage loadImage = new LoadImage();
            loadImage.execute(imageIconPath);
        } else {
            initWondow();
        }
    }

    private Notification initNotificationBar(boolean isPlaying) {

        MusicData dataBean = floatDataList.get(postion);
        if (notificationManager == null)
            notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (builder == null)
            builder = new Notification.Builder(this);

        try {

            if (remoteViews == null) {
                remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notiification);

                Intent playIntent = new Intent(NOTIFICATION_PLAY_PAUSE);
                PendingIntent playPendingIntent = PendingIntent.getBroadcast(this, 0, playIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                remoteViews.setOnClickPendingIntent(R.id.image_start, playPendingIntent);

                Intent preIntent = new Intent(NOTIFICATION_PRE);
                PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, preIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                remoteViews.setOnClickPendingIntent(R.id.image_last, nextPendingIntent);

                Intent nextIntent = new Intent(NOTIFICATION_NEX);
                PendingIntent nextPIntent = PendingIntent.getBroadcast(this, 0, nextIntent, 0);
                remoteViews.setOnClickPendingIntent(R.id.image_next, nextPIntent);

                Intent cancelIntent = new Intent(NOTIFICATION_CANCEL);
                PendingIntent cancelPIntent = PendingIntent.getBroadcast(this, 0, cancelIntent, 0);
                remoteViews.setOnClickPendingIntent(R.id.image_cancle, cancelPIntent);

                PendingIntent pendingIntent = null;
//                try {
//                    Class<?> activiyClass = Class.forName("com.sobey.tvlive2.ui.RadioShowActivity");
////                    Class<?> activiyClass = Class.forName("com.xw.floatlib.MusicActivity");
//                    Intent intent = new Intent();
//                    intent.setClass(this, activiyClass);
//                    intent.putExtra("music_list", (Serializable) floatDataList);
//                    intent.putExtra("music_position", postion);
//                    intent.putExtra("radio_show_id", mPlateID);
//                    intent.putExtra("playState", isPlaying());
////                intent.putExtra("progress", getCurrenPostion());
//                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                    pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
                builder.setContentIntent(pendingIntent)
                        .setContent(remoteViews)
                        .setWhen(System.currentTimeMillis())
                        .setOngoing(false)
                        .setSmallIcon(R.drawable.float_music_icon)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.float_image_icon))
                        .setDefaults(Notification.DEFAULT_ALL);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_LOW);
                    notificationManager.createNotificationChannel(channel);
                    builder.setChannelId(channelID);
                }
                notification = builder.build();
            }

            remoteViews.setImageViewResource(R.id.image_start, isPlaying ? R.drawable.float_image_stop : R.drawable.float_image_start);
            remoteViews.setTextViewText(R.id.music_title, dataBean.getTitle());
            remoteViews.setTextViewText(R.id.music_singer, dataBean.getSinger());

            if (TextUtils.isEmpty(dataBean.getIamgePath()) || imageIcon == null) {
                remoteViews.setImageViewResource(R.id.image_music_icon, R.drawable.float_image_icon);
            } else {
                remoteViews.setImageViewBitmap(R.id.image_music_icon, imageIcon);
            }

            notification.flags |= Notification.FLAG_NO_CLEAR;
            notificationManager.notify(id, notification);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return notification;
    }

    private void upDateNotification(boolean isPlaying) {
        try {
            if (isPlaying) {

                if (notificationManager == null) {
                    startForeground(id, initNotificationBar(isPlaying));
                } else {
                    notificationManager.notify(id, initNotificationBar(true));
                }
            } else {
                stopForeground(false);
                notificationManager.notify(id, initNotificationBar(false));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        FloatWindowManager.startMusic(isPlaying);
    }

    //播放状态
    public boolean isPlaying() {
        return mPlayer.isPlaying();
    }

    //返回歌曲的长度，单位为毫秒
    public int getDuration() {
        return (int) (mPlayer.getDuration() / 1000);
    }

    //返回歌曲目前的进度，单位为毫秒
    public int getCurrenPostion() {
        return (int) (mPlayer.getCurrentPosition() / 1000);
    }

    //设置歌曲播放的进度，单位为毫秒
    public void seekTo(int mesc) {
        mPlayer.seekTo(mesc * 1000);
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            if (stateData == null) stateData = new PlayerStateData();
            if (postion > -1) {
                if (TextUtils.isEmpty(stateData.getMusicId()) || !stateData.getMusicId().equals(floatDataList.get(postion).getMusicId())) {
                    stateData.setAudioName(floatDataList.get(postion).getTitle());
                    stateData.setMusicId(floatDataList.get(postion).getMusicId());
                }

                stateData.setMaxLength(getDuration());
                stateData.setProgress(getCurrenPostion());
//            stateData.setPlayerState(isPlaying());
                if (isPlaying()) {
                    FloatWindowManager.updataProgress(getCurrenPostion(), postion);
                }
                if (callBackMap.get(mPlateID) != null) {
                    callBackMap.get(mPlateID).updateProgress(stateData);
                }
            }

            if (getCurrenPostion() == getDuration() && getDuration() > 0) {
                handler.postDelayed(() -> next(), 1000);
            } else {
                handler.postDelayed(runnable, 1000);
            }

        }
    };

    private BroadcastReceiver NotificationRecever = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();
            if (TextUtils.isEmpty(action)) {
                return;
            }

            if (action.equals(NOTIFICATION_PLAY_PAUSE)) {
                stop2Start();
            } else if (action.equals(NOTIFICATION_PRE)) {
                last();
            } else if (action.equals(NOTIFICATION_NEX)) {
                next();
            } else if (action.equals(NOTIFICATION_CANCEL)) {
                cancle();
            }
        }
    };

    private class LoadImage extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(String... strings) {
            try {
                URL url = new URL(strings[0]);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                //设置固定大小        //需要的大小
                float newWidth = 200f;
                float newHeigth = 200f;
                //图片大小
                int width = myBitmap.getWidth();
                int height = myBitmap.getHeight();

                //缩放比例
                float scaleWidth = newWidth / width;
                float scaleHeigth = newHeigth / height;
                Matrix matrix = new Matrix();
                matrix.postScale(scaleWidth, scaleHeigth);
                Bitmap bitmap = Bitmap.createBitmap(myBitmap, 0, 0, width, height, matrix, true);
                return bitmap;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            imageIcon = bitmap;
            initWondow();
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        FloatWindowManager.setRadioID(mPlateID);
        FloatWindowManager.setMaxProgress(getDuration());
        FloatWindowManager.updataProgress(0, postion);
        if (isFirstInit) isFirstInit = false;
        stop2Start();
    }
}
